package edu.client;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.ValueBoxBase.TextAlignment;

import edu.client.ComprasService.ComprasService;
import edu.client.ComprasService.ComprasServiceAsync;
import edu.shared.DTO.ModoEnvioDTO;
import edu.shared.DTO.OrdenCompraProductoDTO;
import edu.shared.DTO.ProveedorDeProductoDTO;
import edu.shared.DTO.RenglonOrdenCompraProductoDTO;

public class P_EditarOrdenCompraProducto extends Composite {

	// columnas para la tabla productos
	private static final int COL_ELEMENTO = 0;
	private static final int COL_MATERIAL = 1;
	private static final int COL_MEDIDA_FIJA = 2;
	private static final int COL_MEDIDA_VARIABLE_1 = 3;
	private static final int COL_MEDIDA_VARIABLE_2 = 4;
	private static final int COL_CANTIDAD_REQUERIDA = 5;
	private static final int COL_CANTIDAD_COMPRAR = 6;
	private static final int COL_PRECIO = 7;
	private static final int COL_SUBTOTAL = 8;

	private ListBox cbModoEnvio;
	private FlexTable ftRenglones;
	private TextBox totalTB;
	private TextBox tbIVA;
	private TextArea taObservaciones;
	private TextBox tbFormaPago;
	private TextBox proovedorTB;
	private TextBox ultimaFechaEdicionTB;

	private List<ModoEnvioDTO> modosEnvio;
	private List<Double> precios;
	
	private Button btnGenerarOrdenCompra;
	private Button btnGuardarOrdenCompra;
	
	
	private OrdenCompraProductoDTO orden;
	private TabPanel tpPadre;
	private ComprasServiceAsync comprasService;	

	public P_EditarOrdenCompraProducto(TabPanel padre, int idOrden) {
		tpPadre = padre;
		comprasService = GWT.create(ComprasService.class);

		LayoutPanel layoutPanel = new LayoutPanel();
		initWidget(layoutPanel);
		layoutPanel.setSize((Window.getClientWidth() - 55) + "px", "724px");

		Label lblOrdenCompraProducto = new Label("DETALLE DE LA ORDEN DE COMPRA DE PRODUCTOS");
		lblOrdenCompraProducto.setStyleName("labelTitulo");
		layoutPanel.add(lblOrdenCompraProducto);
		layoutPanel.setWidgetLeftWidth(lblOrdenCompraProducto, 2.5, Unit.PCT, 95.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblOrdenCompraProducto, 15.0, Unit.PX, 50.0, Unit.PX);

		Label lblProveedor = new Label("PROOVEDOR:");
		lblProveedor.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		layoutPanel.add(lblProveedor);
		layoutPanel.setWidgetLeftWidth(lblProveedor, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblProveedor, 80.0, Unit.PX, 19.0, Unit.PX);
		
		proovedorTB = new TextBox();
		layoutPanel.add(proovedorTB);
		layoutPanel.setWidgetLeftWidth(proovedorTB, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(proovedorTB, 75.0, Unit.PX, 32.0, Unit.PX);
		proovedorTB.setEnabled(false);

		Label lblUltimaFechaEdicion = new Label("ÚLTIMA FECHA DE EDICIÓN:");
		lblUltimaFechaEdicion.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		layoutPanel.add(lblUltimaFechaEdicion);
		layoutPanel.setWidgetLeftWidth(lblUltimaFechaEdicion, 50.0, Unit.PCT, 19.8, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblUltimaFechaEdicion, 80.0, Unit.PX, 19.0, Unit.PX);

		ultimaFechaEdicionTB = new TextBox();
		layoutPanel.add(ultimaFechaEdicionTB);
		layoutPanel.setWidgetLeftWidth(ultimaFechaEdicionTB, 70.0, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(ultimaFechaEdicionTB, 75.0, Unit.PX, 32.0, Unit.PX);
		ultimaFechaEdicionTB.setEnabled(false);
		
		Label lblModoEnvio = new Label("MODO DE ENVÍO:");
		lblModoEnvio.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		layoutPanel.add(lblModoEnvio);
		layoutPanel.setWidgetLeftWidth(lblModoEnvio, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblModoEnvio, 120.0, Unit.PX, 19.0, Unit.PX);

		cbModoEnvio = new ListBox();
		layoutPanel.add(cbModoEnvio);
		layoutPanel.setWidgetLeftWidth(cbModoEnvio, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(cbModoEnvio, 115.0, Unit.PX, 32.0, Unit.PX);

		Label lblFormaPago = new Label("FORMA DE PAGO:");
		lblFormaPago.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		layoutPanel.add(lblFormaPago);
		layoutPanel.setWidgetLeftWidth(lblFormaPago, 50.0, Unit.PCT, 19.8, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblFormaPago, 120.0, Unit.PX, 19.0, Unit.PX);
		
		tbFormaPago = new TextBox();
		layoutPanel.add(tbFormaPago);
		layoutPanel.setWidgetLeftWidth(tbFormaPago, 70.0, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(tbFormaPago, 115.0, Unit.PX, 32.0, Unit.PX);

		Label lblIVA = new Label("IVA:");
		lblIVA.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		layoutPanel.add(lblIVA);
		layoutPanel.setWidgetLeftWidth(lblIVA, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblIVA, 160.0, Unit.PX, 19.0, Unit.PX);

		tbIVA = new TextBox();
		layoutPanel.add(tbIVA);
		layoutPanel.setWidgetLeftWidth(tbIVA, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(tbIVA, 155.0, Unit.PX, 32.0, Unit.PX);

		Label lblObservaciones = new Label("OBSERVACIONES:");
		lblObservaciones.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		layoutPanel.add(lblObservaciones);
		layoutPanel.setWidgetLeftWidth(lblObservaciones, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblObservaciones, 200.0, Unit.PX, 19.0, Unit.PX);

		taObservaciones = new TextArea();
		layoutPanel.add(taObservaciones);
		layoutPanel.setWidgetLeftWidth(taObservaciones, 17.5, Unit.PCT, 77.5, Unit.PCT);
		layoutPanel.setWidgetTopHeight(taObservaciones, 195.0, Unit.PX, 50.0, Unit.PX);
		
		Label lblProductos = new Label("PRODUCTOS");
		lblProductos.setStyleName("labelTitulo");
		layoutPanel.add(lblProductos);
		layoutPanel.setWidgetLeftWidth(lblProductos, 2.5, Unit.PCT, 95.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblProductos, 240.0, Unit.PX, 50.0, Unit.PX);

		ScrollPanel spProductos = new ScrollPanel();
		spProductos.setStyleName("tabla");
		layoutPanel.add(spProductos);
		layoutPanel.setWidgetLeftWidth(spProductos, 5.0, Unit.PCT, 90.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(spProductos, 310.0, Unit.PX, 250.0, Unit.PX);

		ftRenglones = new FlexTable();
		spProductos.setWidget(ftRenglones);
		ftRenglones.setSize("100%", "100%");

		// cargamos el encabezado de la tabla
		// columna elemento
		ftRenglones.setText(0, COL_ELEMENTO, "ELEMENTO");
		ftRenglones.getCellFormatter().setWidth(0, COL_ELEMENTO, "15%");

		// columna material
		ftRenglones.setText(0, COL_MATERIAL, "MATERIAL");
		ftRenglones.getCellFormatter().setWidth(0, COL_MATERIAL, "15%");

		// columna medida fija
		ftRenglones.setText(0, COL_MEDIDA_FIJA, "MEDIDA FIJA");
		ftRenglones.getCellFormatter().setWidth(0, COL_MEDIDA_FIJA, "10%");

		// columna medida variable 1
		ftRenglones.setText(0, COL_MEDIDA_VARIABLE_1, "MEDIDA VARIABLE 1");
		ftRenglones.getCellFormatter().setWidth(0, COL_MEDIDA_VARIABLE_1, "10%");

		// columna medida variable 2
		ftRenglones.setText(0, COL_MEDIDA_VARIABLE_2, "MEDIDA VARIABLE 2");
		ftRenglones.getCellFormatter().setWidth(0, COL_MEDIDA_VARIABLE_2, "10%");

		// columna cantidad requerida
		ftRenglones.setText(0, COL_CANTIDAD_REQUERIDA, "CANTIDAD REQUERIDA");
		ftRenglones.getCellFormatter().setWidth(0, COL_CANTIDAD_REQUERIDA, "10%");

		// columna cantidad a comprar
		ftRenglones.setText(0, COL_CANTIDAD_COMPRAR, "CANTIDAD A COMPRAR");
		ftRenglones.getCellFormatter().setWidth(0, COL_CANTIDAD_COMPRAR, "10%");

		// columna precio
		ftRenglones.setText(0, COL_PRECIO, "PRECIO");
		ftRenglones.getCellFormatter().setWidth(0, COL_PRECIO, "10%");

		// columna subtotal
		ftRenglones.setText(0, COL_SUBTOTAL, "SUBTOTAL");
		ftRenglones.getCellFormatter().setWidth(0, COL_SUBTOTAL, "10%");

		// seteamos el estilo a los encabezados
		ftRenglones.getRowFormatter().addStyleName(0, "tablaEncabezado");

		Label lblTextoTotal = new Label("TOTAL: $ ");
		layoutPanel.add(lblTextoTotal);
		layoutPanel.setWidgetLeftWidth(lblTextoTotal, 80.0, Unit.PCT, 4.8, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblTextoTotal, 585.0, Unit.PX, 19.0, Unit.PX);
		
		totalTB = new TextBox();
		layoutPanel.add(totalTB);
		layoutPanel.setWidgetLeftWidth(totalTB, 85.0, Unit.PCT, 10.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(totalTB, 580.0, Unit.PX, 32.0, Unit.PX);
		totalTB.setAlignment(TextAlignment.CENTER);
		totalTB.setEnabled(false);

		Label lblPie = new Label("");
		lblPie.setStyleName("labelTitulo");
		layoutPanel.add(lblPie);
		layoutPanel.setWidgetLeftWidth(lblPie, 2.5, Unit.PCT, 95.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(lblPie, 605.0, Unit.PX, 50.0, Unit.PX);

		Button btnCancelar = new Button("");
		btnCancelar.setText("CANCELAR");

		// al presionar el botón cancelar
		btnCancelar.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				salir();
			}
		});

		layoutPanel.add(btnCancelar);
		layoutPanel.setWidgetRightWidth(btnCancelar, 5.0, Unit.PCT, 10.0, Unit.PCT);
		layoutPanel.setWidgetBottomHeight(btnCancelar, 15.0, Unit.PX, 28.0, Unit.PX);

		btnGenerarOrdenCompra = new Button("GENERAR");
		
		// al presionar el botón generar orden de compra
		btnGenerarOrdenCompra.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				
				btnGenerarOrdenCompra.setEnabled(false);
				
				validarDatos("GENERADA");
			}
		});
		
		layoutPanel.add(btnGenerarOrdenCompra);
		layoutPanel.setWidgetRightWidth(btnGenerarOrdenCompra, 17.5, Unit.PCT, 10.0, Unit.PCT);
		layoutPanel.setWidgetBottomHeight(btnGenerarOrdenCompra, 15.0, Unit.PX, 28.0, Unit.PX);

		btnGuardarOrdenCompra = new Button("");
		btnGuardarOrdenCompra.setText("GUARDAR");
		
		// al presionar el botón generar orden de compra
		btnGuardarOrdenCompra.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {
					
					btnGuardarOrdenCompra.setEnabled(false);
					
					validarDatos("GUARDADA");
				}
			});
		
		layoutPanel.add(btnGuardarOrdenCompra);
		layoutPanel.setWidgetRightWidth(btnGuardarOrdenCompra, 30.0, Unit.PCT, 10.0, Unit.PCT);
		layoutPanel.setWidgetBottomHeight(btnGuardarOrdenCompra, 15.0, Unit.PX, 28.0, Unit.PX);
		
		
		cargarOrden(idOrden);
	}

		
	/**
	 * Método que carga la información de la orden de compra de producto
	 */
	private void cargarOrden(int idOrden)
	{		
		comprasService.buscarOrdenCompraProductoCompleta(idOrden, new AsyncCallback<OrdenCompraProductoDTO>(){

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO");				
			}

			@Override
			public void onSuccess(OrdenCompraProductoDTO result) {
				orden = result;
								
				mostrarDatos();
				cargarModosEnvio();
				cargarPrecios();
			}});
	}
	
	/**
	 * Método que muestra en la pantalla los datos de una orden de compra de producto
	 */
	private void mostrarDatos()
	{
		// se utiliza para formatear fechas
		DateTimeFormat formatoFecha = DateTimeFormat.getFormat("dd/MM/yyyy");
		
		proovedorTB.setText(orden.getProveedor());
		ultimaFechaEdicionTB.setText(formatoFecha.format(orden.getUltimaFechaEdicion()));
		tbFormaPago.setText(orden.getFormaPago());
		tbIVA.setText(orden.getIva());
		taObservaciones.setText(orden.getObservaciones());
	}
	
	
	/**
	 * Método que carga el combobox "Modo de envío".
	 */
	private void cargarModosEnvio() {
		comprasService.buscarModosEnvio(new AsyncCallback<List<ModoEnvioDTO>>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO." + "/n" + "/n" + caught.getMessage());
			}

			@Override
			public void onSuccess(List<ModoEnvioDTO> result) {
				modosEnvio = result;

				cbModoEnvio.addItem("SELECCIONE MODO DE ENVÍO");

				int i = 1;
				
				for (ModoEnvioDTO modoEnvio : modosEnvio)
				{
					cbModoEnvio.addItem(modoEnvio.getDescripcion());
				
					if(modoEnvio.getDescripcion().equals(orden.getModoEnvio()))
						cbModoEnvio.setSelectedIndex(i);
					
					i++;
				}
				
			}

		});
	}

	/**
	 * Método que busca y carga los precios de los productos de la orden de compra.
	 */
	private void cargarPrecios()
	{
		List<Integer> idProductos = new LinkedList<Integer>();
		List<RenglonOrdenCompraProductoDTO> renglones = new LinkedList<RenglonOrdenCompraProductoDTO>();
		renglones.addAll(orden.getRenglones());
		
		for(RenglonOrdenCompraProductoDTO renglon : renglones)
			idProductos.add(renglon.getProducto().getIdProducto());	
		
		
		comprasService.buscarPrecios(orden.getProveedor(), idProductos, new AsyncCallback<List<Double>>()
		{

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO." + '\n' + '\n' + caught.getMessage());
			}

			@Override
			public void onSuccess(List<Double> result) {
				precios = result;
				
				//cargamos los renglones de la tabla
				mostrarRenglones();
				
				actualizarTotales();
			}	
		});
	}
	
	
	/**
	 * Método que carga los renglones de la orden de compra
	 */
	private void mostrarRenglones()
	{
		List<RenglonOrdenCompraProductoDTO> renglones = new LinkedList<RenglonOrdenCompraProductoDTO>();
		renglones.addAll(orden.getRenglones());
		
		int numeroFila = 1;
		
		for(RenglonOrdenCompraProductoDTO renglon : renglones)
		{
			//columna elemento
			ftRenglones.setWidget(numeroFila, COL_ELEMENTO, new Label(renglon.getProducto().getElemento().getNombre()));
			ftRenglones.getFlexCellFormatter().setHorizontalAlignment(numeroFila, COL_ELEMENTO, HasHorizontalAlignment.ALIGN_CENTER);
			
			//columna material
			ftRenglones.setWidget(numeroFila, COL_MATERIAL, new Label(renglon.getProducto().getMaterial().getNombre()));
			ftRenglones.getFlexCellFormatter().setHorizontalAlignment(numeroFila, COL_MATERIAL, HasHorizontalAlignment.ALIGN_CENTER);
			
			//columna medida fija
			ftRenglones.setWidget(numeroFila, COL_MEDIDA_FIJA, new Label(renglon.getProducto().getMedidaFija().getMedida()));
			ftRenglones.getFlexCellFormatter().setHorizontalAlignment(numeroFila, COL_MEDIDA_FIJA, HasHorizontalAlignment.ALIGN_CENTER);
			
			//columna medida variable 1
			ftRenglones.setWidget(numeroFila, COL_MEDIDA_VARIABLE_1, new Label(String.valueOf(renglon.getProducto().getMedidaVariable1())));
			ftRenglones.getFlexCellFormatter().setHorizontalAlignment(numeroFila, COL_MEDIDA_VARIABLE_1, HasHorizontalAlignment.ALIGN_CENTER);
			
			//columna medida variable 2
			ftRenglones.setWidget(numeroFila, COL_MEDIDA_VARIABLE_2, new Label(String.valueOf(renglon.getProducto().getMedidaVariable2())));
			ftRenglones.getFlexCellFormatter().setHorizontalAlignment(numeroFila, COL_MEDIDA_VARIABLE_2, HasHorizontalAlignment.ALIGN_CENTER);
			
			String cantidadRequerida = String.valueOf(renglon.getCantidadRequerida());
			
			if(renglon.isEsAdicional())
				cantidadRequerida = " - ";
			
			//columna cantidad requerida
			ftRenglones.setWidget(numeroFila, COL_CANTIDAD_REQUERIDA, new Label(cantidadRequerida));
			ftRenglones.getFlexCellFormatter().setHorizontalAlignment(numeroFila, COL_CANTIDAD_REQUERIDA, HasHorizontalAlignment.ALIGN_CENTER);
			
			final TextBox cantidadAComprar = new TextBox();
			cantidadAComprar.setSize("85%", "85%");
			cantidadAComprar.setText(String.valueOf(renglon.getCantidadAComprar()));
			cantidadAComprar.setStyleName("textBoxTabla");
			
			cantidadAComprar.addChangeHandler(new ChangeHandler() {
				public void onChange(ChangeEvent event) {
					if(cantidadAComprar.getText().equals(""))
						cantidadAComprar.setText("0");
					
					actualizarTotales();
				}
			});

			// columna cantidad a comprar
			ftRenglones.setWidget(numeroFila, COL_CANTIDAD_COMPRAR, cantidadAComprar);
			ftRenglones.getCellFormatter().setWordWrap(numeroFila, COL_CANTIDAD_COMPRAR, true);

			final TextBox precio = new TextBox();
			precio.setSize("85%", "85%");
			precio.setText(String.valueOf(precios.get(numeroFila-1)));
			precio.setStyleName("textBoxTabla");

			precio.addChangeHandler(new ChangeHandler() {
				public void onChange(ChangeEvent event) {
					if(precio.getText().equals(""))
						precio.setText("0");
					
					actualizarTotales();
				}
			});

			// columna precio
			ftRenglones.setWidget(numeroFila, COL_PRECIO, precio);
			ftRenglones.getCellFormatter().setWordWrap(numeroFila, COL_PRECIO, true);

			
			//columna subtotal
			ftRenglones.setWidget(numeroFila, COL_SUBTOTAL, new Label("0"));
			ftRenglones.getFlexCellFormatter().setHorizontalAlignment(numeroFila, COL_SUBTOTAL, HasHorizontalAlignment.ALIGN_CENTER);
			
			//seteamos el estilo de renglón de tabla
			ftRenglones.getRowFormatter().setStyleName(numeroFila, "tablaRenglon");
			
			numeroFila++;
		}
	}
	
	
	/**
	 * Método que actualiza los subtotales de las filas y el total de la tabla
	 */
	private void actualizarTotales()
	{
		try{
			float total = 0;
			
			for(int i=1; i < ftRenglones.getRowCount(); i++)
			{
				//recuperamos los valoes ingresados en los textbox
				String stringCantidad = ((TextBox) ftRenglones.getWidget(i, 6)).getText();
				String stringPrecio = ((TextBox) ftRenglones.getWidget(i, 7)).getText();
				
				float precio = Float.valueOf(stringPrecio);
				float cantidad = Float.valueOf(stringCantidad);
				
				float subtotal = (cantidad * precio)*100/100.00f;			//con "*100/100.00f" logramos redondear el float a 2 decimales 
				
				//actualizamos el subtotal
				Label subtotalLabel = ((Label) ftRenglones.getWidget(i, 8));
				subtotalLabel.setText(String.valueOf(subtotal));
				
				total = total + subtotal;
			}
			
			totalTB.setText(String.valueOf(total));
		}
		
		catch(Exception e){
			Window.alert("Ingrese valores numéricos.");
		}
	}
	
		
	/**
	 * Método que valida los datos cargados en la tabla de productos
	 */
	
	private void validarDatos(String estado)
	{
		try{
			if(cbModoEnvio.getSelectedIndex() == 0)
				throw new Exception("Seleccione el modo de envío.");
			
			for(int i=1; i<ftRenglones.getRowCount(); i++)
			{
				//recuperamos los valores de cantidad requerida, cantidad a comprar y precio
				String stringRequerida = ((Label) ftRenglones.getWidget(i, 5)).getText();
				String stringComprar = ((TextBox) ftRenglones.getWidget(i, 6)).getText();
				String stringPrecio = ((TextBox) ftRenglones.getWidget(i, 7)).getText();
				
				float requerida = 0;
				
				if(!stringRequerida.equals(" - "))
					requerida = Float.parseFloat(stringRequerida);
				
				float comprar = Float.parseFloat(stringComprar);
				Float.parseFloat(stringPrecio);  //aunque no se asigna a una variable nunca, si el parseo lanza una excepción estaríamos frente
												//a un valor no permitido para precio.
				
				if(comprar <= 0)
					throw new Exception("La cantidad a comprar debe ser mayor a cero.");
				
				if(requerida > comprar)
					throw new Exception("La cantidad a comprar debe ser mayor o igual a la cantidad requerida.");
			}
			
			registrarNuevosPrecios();
			crearOrdenCompra(estado);
		}
		
		catch(NumberFormatException nfe)
		{
			Window.alert("Ingrese valores numéricos.");			
			btnGenerarOrdenCompra.setEnabled(true);
			btnGuardarOrdenCompra.setEnabled(true);
		}
		
		catch(Exception e)
		{
			Window.alert(e.getMessage());
			btnGenerarOrdenCompra.setEnabled(true);
			btnGuardarOrdenCompra.setEnabled(true);
		}
	}
	
	/**
	 * Método que actualiza los precios en la base de datos con los que se cargaron en la tabla
	 */
	private void registrarNuevosPrecios()
	{
		List<ProveedorDeProductoDTO> proveedoresDeProducto = new LinkedList<ProveedorDeProductoDTO>();
		
		//recuperamos los renglones de la orden de compra
		List<RenglonOrdenCompraProductoDTO> renglones = new LinkedList<RenglonOrdenCompraProductoDTO>();
		renglones.addAll(orden.getRenglones());
		
		try{
			for(int i=1; i<ftRenglones.getRowCount(); i++)
			{
				//recuperamos los valores de cantidad requerida, cantidad a comprar y precio
				String stringPrecio = ((TextBox) ftRenglones.getWidget(i, 7)).getText();
				
				double precio = Double.parseDouble(stringPrecio);
				
				//creamos el objeto DTO y cargamos sus datos
				ProveedorDeProductoDTO proveedorDeProducto = new ProveedorDeProductoDTO();
				proveedorDeProducto.getProducto().setIdProducto(renglones.get(i-1).getProducto().getIdProducto());
				proveedorDeProducto.getProveedor().setNombre(orden.getProveedor());
				proveedorDeProducto.setPrecio(precio);
				
				proveedoresDeProducto.add(proveedorDeProducto);
			}
			
			comprasService.registrarPrecios(proveedoresDeProducto, new AsyncCallback<Boolean>()
			{

				@Override
				public void onFailure(Throwable caught) {
					Window.alert("ERROR EN EL SERVICIO." + '\n' + '\n' + caught.getMessage());		
					btnGenerarOrdenCompra.setEnabled(true);
					btnGuardarOrdenCompra.setEnabled(true);
				}

				@Override
				public void onSuccess(Boolean result) {
					
				}
			});
		}
		
		catch(NumberFormatException nfe)
		{
			Window.alert("Algunos precios tienen valores no permitidos.");	
			btnGenerarOrdenCompra.setEnabled(true);
			btnGuardarOrdenCompra.setEnabled(true);
		}
	}
	
	/**
	 * Método que crea la orden de compra con sus renglones.
	 */
	private void crearOrdenCompra(String estado)
	{
		//buscamos el modo de envió seleccionado. Si no se seleccionó ninguno, lo setamos como null.
		String modoEnvio = cbModoEnvio.getValue(cbModoEnvio.getSelectedIndex());
		
		if(modoEnvio.equals("< SELECCIONE >"))
			modoEnvio = null;
		
		//buscamos el valor ingresado para el iva
		String iva = tbIVA.getText();
		
		//buscamos el valor ingresado para observaciones
		String observaciones = taObservaciones.getText();
		
		//buscamos el valor ingresado para forma de pago
		String formaPago = tbFormaPago.getText();
		
		
		
		//creamos la orden de compra de producto y le seteamos sus valores
		OrdenCompraProductoDTO ordenCompra = new OrdenCompraProductoDTO();
		
		ordenCompra.setIdOrden(orden.getIdOrden());
		ordenCompra.setProveedor(orden.getProveedor());
		ordenCompra.setModoEnvio(modoEnvio);
		ordenCompra.setUltimaFechaEdicion(new Date());
		ordenCompra.setFechaGeneracion(orden.getFechaGeneracion());
		ordenCompra.setIva(iva);
		ordenCompra.setObservaciones(observaciones);
		ordenCompra.setEstado(estado);
		ordenCompra.setFormaPago(formaPago);
		
		
		
		//creamos los renglones de la orden de compra de productos
		List<RenglonOrdenCompraProductoDTO> nuevosRenglones = new LinkedList<RenglonOrdenCompraProductoDTO>();
		
		//recuperamos los renglones de la orden de compra
		List<RenglonOrdenCompraProductoDTO> renglones = new LinkedList<RenglonOrdenCompraProductoDTO>();
		renglones.addAll(orden.getRenglones());
		
		for(int i=1; i<ftRenglones.getRowCount(); i++)
		{
			//recuperamos la cantidad a comprar ingresada
			int cantidadComprar = Integer.parseInt(((TextBox) ftRenglones.getWidget(i, 6)).getText());
			
			
			RenglonOrdenCompraProductoDTO renglon = new RenglonOrdenCompraProductoDTO();
			renglon.setIdRenglon(renglones.get(i-1).getIdRenglon());
			renglon.setCantidadAComprar(cantidadComprar);
			
			nuevosRenglones.add(renglon);
		}
		
		comprasService.registrarOrdenCompraProducto(ordenCompra, nuevosRenglones, null, new AsyncCallback<Integer>()
		{
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO." + '\n' + '\n' + caught.getMessage());
				btnGenerarOrdenCompra.setEnabled(true);				
				btnGuardarOrdenCompra.setEnabled(true);
			}

			@Override
			public void onSuccess(Integer result) {			
				Window.alert("La orden de compra de producto ha sido procesada correctamente.");
				salir();
			}	
		});
	}
		
	/**
	 * Método que vuelve a la pantalla inmediatamente anterior a la presente.
	 */
	private void salir() {

		int ancho = Window.getClientWidth() - 15;
		int alto = Window.getClientHeight() - 13;

		P_EditarOrdenCompraProductoSeleccion p_crearOrdenFabricacionSeleccion = new P_EditarOrdenCompraProductoSeleccion(tpPadre);

		this.getParent().removeFromParent();
		ScrollPanel formulario = new ScrollPanel();
		formulario.setTitle("EDITAR ORDEN COMPRA PRODUCTO");
		formulario.setStyleName("panelFormulario");
		formulario.setSize((ancho - 25) + "px", (alto - 145) + "px");
		formulario.add(p_crearOrdenFabricacionSeleccion);
		tpPadre.add(formulario, "EDITAR ORDEN COMPRA PRODUCTO", false);
		tpPadre.selectTab(Validaciones.numeroElemento(tpPadre, "EDITAR ORDEN COMPRA PRODUCTO"));

		tpPadre.setSize((ancho - 5) + "px", (alto - 90) + "px");

		for (int i = 0; i < tpPadre.getWidgetCount(); i++) {
			tpPadre.getWidget(i).setSize((ancho - 20) + "px", (alto - 145) + "px");
		}
	}
}
